home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / warp / intrp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  12.0 KB  |  591 lines

  1. /* $Header: /b/iv/src/warp/RCS/intrp.c,v 1.1 1993/06/11 20:09:13 iv Exp iv $
  2.  *
  3.  * Revision 7.0.1.2  86/12/12  16:59:04  lwall
  4.  * Baseline for net release.
  5.  * 
  6.  * Revision 7.0.1.1  86/10/16  10:51:43  lwall
  7.  * Added Damage.  Fixed random bugs.
  8.  * 
  9.  * Revision 7.0  86/10/08  15:12:19  lwall
  10.  * Split into separate files.  Added amoebas and pirates.
  11.  * 
  12.  */
  13.  
  14. #include "EXTERN.h"
  15. #include "warp.h"
  16. #include "sig.h"
  17. #include "util.h"
  18. #include "term.h"
  19. #include "INTERN.h"
  20. #include "intrp.h"
  21.  
  22. /* name of this host */
  23.     char *hostname;
  24.  
  25. #ifdef TILDENAME
  26. static char *tildename = Nullch;
  27. static char *tildedir = Nullch;
  28. #endif
  29.  
  30. char *dointerp();
  31. char *getrealname();
  32. #ifdef CONDSUB
  33. char *skipinterp();
  34. #endif
  35.  
  36. static void abort_interp();
  37.  
  38. void
  39. intrp_init(tcbuf)
  40. char *tcbuf;
  41. {
  42.     char *getlogin();
  43.  
  44.     /* get environmental stuff */
  45.  
  46.     /* get home directory */
  47.  
  48.     homedir = getenv("HOME");
  49.     if (homedir == Nullch)
  50.     homedir = getenv("LOGDIR");
  51.  
  52.     dotdir = getval("DOTDIR",homedir);
  53.  
  54.     /* get login name */
  55.  
  56.     logname = getenv("USER");
  57.     if (logname == Nullch)
  58.     logname = getenv("LOGNAME");
  59. #ifdef GETLOGIN
  60.     if (logname == Nullch)
  61.     logname = savestr(getlogin());
  62. #endif
  63.     
  64.     /* get the real name of the person (%N) */
  65.     /* Must be done after logname is read in because BERKNAMES uses that */
  66.  
  67.     strcpy(tcbuf,getrealname(getuid()));
  68.     realname = savestr(tcbuf);
  69.  
  70.     /* name of this host (%H) */
  71.  
  72.     gethostname(buf,sizeof buf);
  73.     hostname = savestr(buf);
  74.     if (index(hostname,'.'))
  75.     hostname = savestr(hostname);
  76.     else {
  77.     char hname[128];
  78.  
  79.     strcpy(hname,hostname);
  80.     strcat(hname,MYDOMAIN);
  81.     hostname=savestr(hname);
  82.     }
  83.     warplib = savestr(filexp(WARPLIB));
  84.  
  85.     if (scorespec)            /* that getwd below takes ~1/3 sec. */
  86.     return;                /* and we do not need it for -s */
  87.     (void) getwd(tcbuf);        /* find working directory name */
  88.     origdir = savestr(tcbuf);        /* and remember it */
  89. }
  90.  
  91. /* expand filename via %, ~, and $ interpretation */
  92. /* returns pointer to static area */
  93. /* Note that there is a 1-deep cache of ~name interpretation */
  94.  
  95. char *
  96. filexp(s)
  97. Reg1 char *s;
  98. {
  99.     static char filename[CBUFLEN];
  100.     char scrbuf[CBUFLEN];
  101.     Reg2 char *d;
  102.  
  103. #ifdef DEBUGGING
  104.     if (debug & DEB_FILEXP)
  105.     printf("< %s\r\n",s);
  106. #endif
  107.     interp(filename, (sizeof filename), s);            /* interpret any % escapes */
  108. #ifdef DEBUGGING
  109.     if (debug & DEB_FILEXP)
  110.     printf("%% %s\r\n",filename);
  111. #endif
  112.     s = filename;
  113.     if (*s == '~') {    /* does destination start with ~? */
  114.     if (!*(++s) || *s == '/') {
  115.         Sprintf(scrbuf,"%s%s",homedir,s);
  116.                 /* swap $HOME for it */
  117. #ifdef DEBUGGING
  118.     if (debug & DEB_FILEXP)
  119.     printf("~ %s\r\n",scrbuf);
  120. #endif
  121.         strcpy(filename,scrbuf);
  122.     }
  123.     else {
  124. #ifdef TILDENAME
  125.         for (d=scrbuf; isalnum(*s); s++,d++)
  126.         *d = *s;
  127.         *d = '\0';
  128.         if (tildedir && strEQ(tildename,scrbuf)) {
  129.         strcpy(scrbuf,tildedir);
  130.         strcat(scrbuf, s);
  131.         strcpy(filename, scrbuf);
  132. #ifdef DEBUGGING
  133.         if (debug & DEB_FILEXP)
  134.             printf("r %s %s\r\n",tildename,tildedir);
  135. #endif
  136.         }
  137.         else {
  138.         if (tildename) {
  139.             free(tildename);
  140.             free(tildedir);
  141.         }
  142.         tildedir = Nullch;
  143.         tildename = savestr(scrbuf);
  144.         {
  145.             struct passwd *getpwnam();
  146.             struct passwd *pwd = getpwnam(tildename);
  147.  
  148.             Sprintf(scrbuf,"%s%s",pwd->pw_dir,s);
  149.             tildedir = savestr(pwd->pw_dir);
  150.             strcpy(filename,scrbuf);
  151.             endpwent();
  152.         }
  153.         }
  154. #else /* !TILDENAME */
  155. #ifdef VERBOSE
  156.         IF(verbose)
  157.         fputs("~loginname not implemented.\r\n",stdout);
  158.         ELSE
  159. #endif
  160. #ifdef TERSE
  161.         fputs("~login not impl.\r\n",stdout);
  162. #endif
  163. #endif
  164.     }
  165.     }
  166.     else if (*s == '$') {    /* starts with some env variable? */
  167.     d = scrbuf;
  168.     *d++ = '%';
  169.     if (s[1] == '{')
  170.         strcpy(d,s+2);
  171.     else {
  172.         *d++ = '{';
  173.         for (s++; isalnum(*s); s++) *d++ = *s;
  174.                 /* skip over token */
  175.         *d++ = '}';
  176.         strcpy(d,s);
  177.     }
  178. #ifdef DEBUGGING
  179.     if (debug & DEB_FILEXP)
  180.         printf("$ %s\r\n",scrbuf);
  181. #endif
  182.     interp(filename, (sizeof filename), scrbuf);
  183.                     /* this might do some extra '%'s but */
  184.                     /* that is how the Mercedes Benz */
  185.     }
  186. #ifdef DEBUGGING
  187.     if (debug & DEB_FILEXP)
  188.     printf("> %s\r\n",filename);
  189. #endif
  190.     return filename;
  191. }
  192.  
  193. #ifdef CONDSUB
  194. /* skip interpolations */
  195.  
  196. char *
  197. skipinterp(pattern,stoppers)
  198. Reg1 char *pattern;
  199. char *stoppers;
  200. {
  201.  
  202.     while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
  203. #ifdef DEBUGGING
  204.     if (debug & 8)
  205.         printf("skipinterp till %s at %s\r\n",stoppers?stoppers:"",pattern);
  206. #endif
  207.     if (*pattern == '%' && pattern[1]) {
  208.         switch (*++pattern) {
  209.         case '{':
  210.         for (pattern++; *pattern && *pattern != '}'; pattern++)
  211.             if (*pattern == '\\')
  212.             pattern++;
  213.         break;
  214. #ifdef CONDSUB
  215.         case '(': {
  216.         pattern = skipinterp(pattern+1,"!=");
  217.         if (!*pattern)
  218.             goto getout;
  219.         for (pattern++; *pattern && *pattern != '?'; pattern++)
  220.             if (*pattern == '\\')
  221.             pattern++;
  222.         if (!*pattern)
  223.             goto getout;
  224.         pattern = skipinterp(pattern+1,":)");
  225.         if (*pattern == ':')
  226.             pattern = skipinterp(pattern+1,")");
  227.         break;
  228.         }
  229. #endif
  230. #ifdef BACKTICK
  231.         case '`': {
  232.         pattern = skipinterp(pattern+1,"`");
  233.         break;
  234.         }
  235. #endif
  236. #ifdef PROMPTTTY
  237.         case '"':
  238.         pattern = skipinterp(pattern+1,"\"");
  239.         break;
  240. #endif
  241.         default:
  242.         break;
  243.         }
  244.         pattern++;
  245.     }
  246.     else {
  247.         if (*pattern == '^' && pattern[1])
  248.         pattern += 2;
  249.         else if (*pattern == '\\' && pattern[1])
  250.         pattern += 2;
  251.         else
  252.         pattern++;
  253.     }
  254.     }
  255. getout:
  256.     return pattern;            /* where we left off */
  257. }
  258. #endif
  259.  
  260. /* interpret interpolations */
  261.  
  262. char *
  263. dointerp(dest,destsize,pattern,stoppers)
  264. Reg1 char *dest;
  265. Reg2 int destsize;
  266. Reg3 char *pattern;
  267. char *stoppers;
  268. {
  269.     Reg4 char *s;
  270.     Reg5 int i;
  271.     char scrbuf[512];
  272.     bool upper = FALSE;
  273.     bool lastcomp = FALSE;
  274.     int metabit = 0;
  275.  
  276.     while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
  277. #ifdef DEBUGGING
  278.     if (debug & 8)
  279.         printf("dointerp till %s at %s\r\n",stoppers?stoppers:"",pattern);
  280. #endif
  281.     if (*pattern == '%' && pattern[1]) {
  282.         upper = FALSE;
  283.         lastcomp = FALSE;
  284.         for (s=Nullch; !s; ) {
  285.         switch (*++pattern) {
  286.         case '^':
  287.             upper = TRUE;
  288.             break;
  289.         case '_':
  290.             lastcomp = TRUE;
  291.             break;
  292.         case '{':
  293.             pattern = cpytill(scrbuf,pattern+1,'}');
  294.             if (s = index(scrbuf,'-'))
  295.             *s++ = '\0';
  296.             else
  297.             s = nullstr;
  298.             s = getval(scrbuf,s);
  299.             break;
  300. #ifdef CONDSUB
  301.         case '(': {
  302.             char rch;
  303.             bool matched;
  304.             
  305.             pattern = dointerp(dest,destsize,pattern+1,"!=");
  306.             rch = *pattern;
  307.             if (rch == '!')
  308.             pattern++;
  309.             if (*pattern != '=')
  310.             goto getout;
  311.             pattern = cpytill(scrbuf,pattern+1,'?');
  312.             if (!*pattern)
  313.             goto getout;
  314.             if (*scrbuf == '^' && scrbuf[strlen(scrbuf)-1] == '$') {
  315.             scrbuf[strlen(scrbuf)-1] = '\0';
  316.             matched = strEQ(scrbuf+1,dest);
  317.             }
  318.             else
  319.             matched = instr(dest,scrbuf) != Nullch;
  320.             if (matched==(rch == '=')) {
  321.             pattern = dointerp(dest,destsize,pattern+1,":)");
  322.             if (*pattern == ':')
  323.                 pattern = skipinterp(pattern+1,")");
  324.             }
  325.             else {
  326.             pattern = skipinterp(pattern+1,":)");
  327.             if (*pattern == ':')
  328.                 pattern++;
  329.             pattern = dointerp(dest,destsize,pattern,")");
  330.             }
  331.             s = dest;
  332.             break;
  333.         }
  334. #endif
  335. #ifdef BACKTICK
  336.         case '`': {
  337.             FILE *pipefp, *popen();
  338.  
  339.             pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"`");
  340.             pipefp = popen(scrbuf,"r");
  341.             if (pipefp != Nullfp) {
  342.             int len;
  343.  
  344.             len = fread(scrbuf,sizeof(char),(sizeof scrbuf)-1,
  345.                 pipefp);
  346.             scrbuf[len] = '\0';
  347.             pclose(pipefp);
  348.             }
  349.             else {
  350.             printf("\r\nCan't run %s\r\n",scrbuf);
  351.             *scrbuf = '\0';
  352.             }
  353.             for (s=scrbuf; *s; s++) {
  354.             if (*s == '\n') {
  355.                 if (s[1])
  356.                 *s = ' ';
  357.                 else
  358.                 *s = '\0';
  359.             }
  360.             }
  361.             s = scrbuf;
  362.             break;
  363.         }
  364. #endif
  365. #ifdef PROMPTTTY
  366.         case '"':
  367.             pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"\"");
  368.             fputs(scrbuf,stdout);
  369.             resetty();
  370.             gets(scrbuf);
  371.             crmode();
  372.             raw();
  373.             noecho();
  374.             nonl();
  375.             s = scrbuf;
  376.             break;
  377. #endif
  378.         case '~':
  379.             s = homedir;
  380.             break;
  381.         case '.':
  382.             s = dotdir;
  383.             break;
  384.         case '$':
  385.             s = scrbuf;
  386.             Sprintf(s,"%d",getpid());
  387.             break;
  388.         case 'H':            /* host name */
  389.             s = hostname;
  390.             break;
  391.         case 'L':            /* login id */
  392.             s = logname;
  393.             break;
  394.         case 'N':            /* full name */
  395.             s = getval("NAME",realname);
  396.             break;
  397.         case 'O':
  398.             s = origdir;
  399.             break;
  400.         case 'p':
  401.             s = cwd;
  402.             break;
  403.         case 'X':            /* warp library */
  404.             s = warplib;
  405.             break;
  406.         default:
  407.             if (--destsize <= 0)
  408.             abort_interp();
  409.             *dest++ = *pattern | metabit;
  410.             s = nullstr;
  411.             break;
  412.         }
  413.         }
  414.         if (!s)
  415.         s = nullstr;
  416.         pattern++;
  417.         if (upper || lastcomp) {
  418.         char *t;
  419.  
  420.         if (s != scrbuf) {
  421.             Safecpy(scrbuf,s,(sizeof scrbuf));
  422.             s = scrbuf;
  423.         }
  424.         if (upper || !(t=rindex(s,'/')))
  425.             t = s;
  426.         while (*t && !isalpha(*t))
  427.             t++;
  428.         if (islower(*t))
  429.             *t = toupper(*t);
  430.         }
  431.         i = metabit;        /* maybe get into register */
  432.         if (s == dest) {
  433.         while (*dest) {
  434.             if (--destsize <= 0)
  435.             abort_interp();
  436.             *dest++ |= i;
  437.         }
  438.         }
  439.         else {
  440.         while (*s) {
  441.             if (--destsize <= 0)
  442.             abort_interp();
  443.             *dest++ = *s++ | i;
  444.         }
  445.         }
  446.     }
  447.     else {
  448.         if (--destsize <= 0)
  449.         abort_interp();
  450.         if (*pattern == '^' && pattern[1]) {
  451.         ++pattern;            /* skip uparrow */
  452.         i = *pattern;        /* get char into a register */
  453.         if (i == '?')
  454.             *dest++ = '\177' | metabit;
  455.         else if (i == '(') {
  456.             metabit = 0200;
  457.             destsize++;
  458.         }
  459.         else if (i == ')') {
  460.             metabit = 0;
  461.             destsize++;
  462.         }
  463.         else
  464.             *dest++ = i & 037 | metabit;
  465.         pattern++;
  466.         }
  467.         else if (*pattern == '\\' && pattern[1]) {
  468.         ++pattern;            /* skip backslash */
  469.         i = *pattern;        /* get char into a register */
  470.     
  471.         /* this used to be a switch but the if may save space */
  472.         
  473.         if (i >= '0' && i <= '7') {
  474.             i = 1;
  475.             while (i < 01000 && *pattern >= '0' && *pattern <= '7') {
  476.             i <<= 3;
  477.             i += *pattern++ - '0';
  478.             }
  479.             *dest++ = i & 0377 | metabit;
  480.             --pattern;
  481.         }
  482.         else if (i == 'b')
  483.             *dest++ = '\b' | metabit;
  484.         else if (i == 'f')
  485.             *dest++ = '\f' | metabit;
  486.         else if (i == 'n')
  487.             *dest++ = '\n' | metabit;
  488.         else if (i == 'r')
  489.             *dest++ = '\r' | metabit;
  490.         else if (i == 't')
  491.             *dest++ = '\t' | metabit;
  492.         else
  493.             *dest++ = i | metabit;
  494.         pattern++;
  495.         }
  496.         else
  497.         *dest++ = *pattern++ | metabit;
  498.     }
  499.     }
  500.     *dest = '\0';
  501. getout:
  502.     return pattern;            /* where we left off */
  503. }
  504.  
  505. void
  506. interp(dest,destsize,pattern)
  507. char *dest;
  508. int destsize;
  509. char *pattern;
  510. {
  511.     (void) dointerp(dest,destsize,pattern,Nullch);
  512. #ifdef DEBUGGING
  513.     if (debug & DEB_FILEXP)
  514.     fputs(dest,stdout);
  515. #endif
  516. }
  517.  
  518. /* get the person's real name from /etc/passwd */
  519. /* (string is overwritten, so it must be copied) */
  520.  
  521. char *
  522. getrealname(uid)
  523. int uid;
  524. {
  525.     char *s, *c;
  526.  
  527. #ifdef PASSNAMES
  528.     struct passwd *pwd = getpwuid(uid);
  529.     
  530.     s = pwd->pw_gecos;
  531. #ifdef BERKNAMES
  532. #ifdef BERKJUNK
  533.     while (*s && !isalnum(*s) && *s != '&') s++;
  534. #endif
  535.     if ((c = index(s, ',')) != Nullch)
  536.     *c = '\0';
  537.     if ((c = index(s, ';')) != Nullch)
  538.     *c = '\0';
  539.     s = cpytill(buf,s,'&');
  540.     if (*s == '&') {            /* whoever thought this one up was */
  541.     c = buf + strlen(buf);        /* in the middle of the night */
  542.     strcat(c,logname);        /* before the morning after */
  543.     strcat(c,s+1);
  544.     if (islower(*c))
  545.         *c = toupper(*c);        /* gack and double gack */
  546.     }
  547. #else
  548.     if ((c = index(s, '(')) != Nullch)
  549.     *c = '\0';
  550.     if ((c = index(s, '-')) != Nullch)
  551.     s = c;
  552.     strcpy(buf,tmpbuf);
  553. #endif
  554.     endpwent();
  555.     return buf;                /* return something static */
  556. #else
  557.     if ((tmpfp=fopen(filexp(FULLNAMEFILE),"r")) != Nullfp) {
  558.     Fgets(buf,sizeof buf,tmpfp);
  559.     Fclose(tmpfp);
  560.     }
  561.     else {
  562.     resetty();
  563.     printf("What is your name? ");
  564.     Fgets(buf,(sizeof buf),stdin);
  565.     crmode();
  566.     raw();
  567.     noecho();
  568.     nonl();
  569.     if (fork())
  570.         wait(0);
  571.     else {
  572.         setuid(getuid());
  573.         if ((tmpfp = fopen(filexp(FULLNAMEFILE),"w")) == NULL)
  574.         exit(1);
  575.         fprintf(tmpfp, "%s\n", buf);
  576.         Fclose(tmpfp);
  577.         exit(0);
  578.     }
  579.     }
  580.     buf[strlen(buf)-1] = '\0';
  581.     return buf;
  582. #endif
  583. }
  584.  
  585. static void
  586. abort_interp()
  587. {
  588.     fputs("\r\n% interp buffer overflow!\r\n",stdout);
  589.     sig_catcher(0);
  590. }
  591.